﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ValidationTestModel.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the ValidationTestModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.ComponentModel.Modelling.TestAssets
{
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;

    [CustomValidation(typeof(ValidationTestModel), "ValidatePercentages")]
    public class ValidationTestModel : TestModelBase
    {
        #region Fields

        private string _mutuallyExclusiveValueX;
        private string _mutuallyExclusiveValueY;
        private string _requiredValue;
        private int _rangeValue;
        private int _percentageX;
        private int _percentageY;

        #endregion

        /// <summary>
        /// Gets or sets the required value.
        /// </summary>
        /// <value>The required value.</value>
        [Required, Display(Name = "Custom Display Name")]
        public string RequiredValue
        {
            get { return _requiredValue; }
            set { SetProperty(ref _requiredValue, value, () => RequiredValue); }
        }

        [Range(0, 100)]
        public int RangeValue
        {
            get { return _rangeValue; }
            set { SetProperty(ref _rangeValue, value, () => RangeValue); }
        }

        /// <summary>
        /// Gets or sets the mutual value X (mutually exclusive with <see cref="MutuallyExclusiveValueY"/>.
        /// </summary>
        /// <value>The mutual value X.</value>
        public string MutuallyExclusiveValueX
        {
            get
            {
                return _mutuallyExclusiveValueX;
            }
            set
            {
                SetProperty(ref _mutuallyExclusiveValueX, value, () => MutuallyExclusiveValueX,
                    (o, n) => ValidateMutuallyExclusiveProperties());
            }
        }

        /// <summary>
        /// Gets or sets the mutual value Y (mutually exclusive with <see cref="MutuallyExclusiveValueX"/>.
        /// </summary>
        /// <value>The mutual value Y.</value>
        public string MutuallyExclusiveValueY
        {
            get
            {
                return _mutuallyExclusiveValueY;
            }
            set
            {
                SetProperty(ref _mutuallyExclusiveValueY, value, () => MutuallyExclusiveValueY,
                    (o, n) => ValidateMutuallyExclusiveProperties());
            }
        }

        /// <summary>
        /// Gets the errors.
        /// </summary>
        /// <value>The errors.</value>
        public IDataErrorInfo Errors
        {
            get { return this; }
        }

        /// <summary>
        /// Override <see cref="OnValidate"/> to ensure that our custom validation is invoked.
        /// </summary>
        protected override void OnValidate()
        {
            base.OnValidate();
            ValidateMutuallyExclusiveProperties();
        }
        
        [Range(0, 100)]
        public int PercentageX
        {
            get { return _percentageX; }
            set { SetProperty(ref _percentageX, value, () => PercentageX); }
        }

        [Range(0, 100)]
        public int PercentageY
        {
            get { return _percentageY; }
            set { SetProperty(ref _percentageY, value, () => PercentageY); }
        }
        
        /// <summary>
        /// Validates the mutually exclusive properties.
        /// </summary>
        protected void ValidateMutuallyExclusiveProperties()
        {
            // Checking for IsDeserializing is optional, depending on desired error behavior and performance requirements
            if (!IsDeserializing)
            {
                const string Message = @"Exactly one of MutuallyExclusiveValueX or MutuallyExclusiveValueY must be set.";
                if (String.IsNullOrEmpty(MutuallyExclusiveValueX) == String.IsNullOrEmpty(MutuallyExclusiveValueY))
                {
                    AddError("MutuallyExclusiveValueX", Message);
                    AddError("MutuallyExclusiveValueY", Message);
                }
                else
                {
                    RemoveError("MutuallyExclusiveValueX", Message);
                    RemoveError("MutuallyExclusiveValueY", Message);
                }
            }
        }

        public static ValidationResult ValidatePercentages(ValidationTestModel model)
        {
            return model.PercentageX + model.PercentageY != 100 ? 
                new ValidationResult("PercentageX and PercentageY must add up 100.") : ValidationResult.Success;
        }
    }
}